package com.wzb.mybatisplus.bitaction.electrumaction.four;

import java.math.BigInteger;
import java.util.Arrays;

public class WIFPrivateKeyConverter {

    // Base58字符集
    private static final String BASE58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
    private static final BigInteger BIG_58 = BigInteger.valueOf(58);

    /**
     * Base58解码
     */
    public static byte[] base58Decode(String input) {
        BigInteger num = BigInteger.ZERO;

        // 将Base58字符串转换为BigInteger
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            int index = BASE58.indexOf(c);
            if (index == -1) {
                throw new IllegalArgumentException("Invalid Base58 character: " + c);
            }
            num = num.multiply(BIG_58).add(BigInteger.valueOf(index));
        }

        // 转换为字节数组
        byte[] bytes = num.toByteArray();

        // 处理前导零
        int zeros = 0;
        for (int i = 0; i < input.length() && input.charAt(i) == '1'; i++) {
            zeros++;
        }

        if (zeros > 0) {
            byte[] tmp = new byte[bytes.length + zeros];
            System.arraycopy(bytes, 0, tmp, zeros, bytes.length);
            bytes = tmp;
        }

        return bytes;
    }

    /**
     * 验证校验和
     */
    private static boolean verifyChecksum(byte[] payload) {
        if (payload.length < 4) return false;

        byte[] data = Arrays.copyOfRange(payload, 0, payload.length - 4);
        byte[] checksum = Arrays.copyOfRange(payload, payload.length - 4, payload.length);

        // 计算双SHA256哈希
        byte[] hash1 = sha256(data);
        byte[] hash2 = sha256(hash1);

        byte[] calculatedChecksum = Arrays.copyOfRange(hash2, 0, 4);

        return Arrays.equals(checksum, calculatedChecksum);
    }

    /**
     * SHA256哈希计算
     */
    private static byte[] sha256(byte[] data) {
        try {
            java.security.MessageDigest digest = java.security.MessageDigest.getInstance("SHA-256");
            return digest.digest(data);
        } catch (Exception e) {
            throw new RuntimeException("SHA-256 not available", e);
        }
    }

    /**
     * 提取原始私钥字节（移除版本字节和校验和）
     */
    public static byte[] extractPrivateKeyBytes(byte[] decodedBytes) {
        if (!verifyChecksum(decodedBytes)) {
            throw new IllegalArgumentException("Invalid checksum");
        }

        // WIF格式结构: [版本字节(1)] + [私钥(32)] + [压缩标志(可选1)] + [校验和(4)]
        if (decodedBytes.length == 37) {
            // 非压缩私钥: 1版本 + 32私钥 + 4校验和
            return Arrays.copyOfRange(decodedBytes, 1, 33);
        } else if (decodedBytes.length == 38) {
            // 压缩私钥: 1版本 + 32私钥 + 1压缩标志(0x01) + 4校验和
            return Arrays.copyOfRange(decodedBytes, 1, 33);
        } else {
            throw new IllegalArgumentException("Invalid WIF format length");
        }
    }

    /**
     * 字节数组转十六进制字符串
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    /**
     * 字节数组转十进制字符串
     */
    public static String bytesToDecimal(byte[] bytes) {
        BigInteger bigInt = new BigInteger(1, bytes);
        return bigInt.toString();
    }

    /**
     * 主转换方法
     */
    public static ConversionResult convertWIFToHexAndDecimal(String wifPrivateKey) {
        // 验证输入格式
        if (wifPrivateKey == null || wifPrivateKey.isEmpty()) {
            throw new IllegalArgumentException("Private key cannot be null or empty");
        }

        char firstChar = wifPrivateKey.charAt(0);
        if (firstChar != '5' && firstChar != 'L' && firstChar != 'K') {
            throw new IllegalArgumentException("Private key must start with 5, L, or K");
        }

        try {
            // Base58解码
            byte[] decodedBytes = base58Decode(wifPrivateKey);

            // 提取私钥字节
            byte[] privateKeyBytes = extractPrivateKeyBytes(decodedBytes);

            // 转换为十六进制和十进制
            String hex = bytesToHex(privateKeyBytes);
            String decimal = bytesToDecimal(privateKeyBytes);

            return new ConversionResult(hex, decimal);

        } catch (Exception e) {
            throw new RuntimeException("Failed to convert private key: " + e.getMessage(), e);
        }
    }


    /**
     * 转换结果类
     */
    public static class ConversionResult {
        private final String hex;
        private final String decimal;

        public ConversionResult(String hex, String decimal) {
            this.hex = hex;
            this.decimal = decimal;
        }

        public String getHex() { return hex; }
        public String getDecimal() { return decimal; }

        @Override
        public String toString() {
            return String.format("Hex: %s\nDecimal: %s", hex, decimal);
        }
    }
}